package pl.edu.pw.elka.GIS.UI;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Random;

import com.sun.org.apache.bcel.internal.generic.RETURN;
import com.trolltech.qt.QSignalEmitter.AbstractSignal;
import com.trolltech.qt.core.QModelIndex;
import com.trolltech.qt.core.Qt.ItemDataRole;
import com.trolltech.qt.core.Qt.Orientation;
import com.trolltech.qt.gui.QAbstractTableModel;
import com.trolltech.qt.gui.QColor;
import com.trolltech.qt.gui.QMessageBox;

import pl.edu.pw.elka.GIS.graph.Graph;

public class GraphFile extends QAbstractTableModel 
{
	private String fileName;
	private String directory;
	private Graph graph;
	
	public Signal1<Integer> vertexCountChanged = new Signal1<Integer>();
	
	public GraphFile(String directory, String fileName)
	{
		this.fileName = fileName;
		this.directory = directory;
		graph = new Graph();
	}
	
	@Override
	public Object data(QModelIndex index, int role)
	{
		if (graph.isConection(index.row(), index.column()))
		{
			switch (role)
			{
			case ItemDataRole.BackgroundRole:
				return QColor.red;

			case ItemDataRole.DisplayRole:
				return "1";
			}
		}
		else
		{
			switch (role)
			{
			case ItemDataRole.DisplayRole:
				return "0";
			}
		}
	
		
		return null;
	}
	
	@Override
	public int rowCount(QModelIndex parent)
	{
		return graph.getVertexCount();
	}
	
	@Override
	public int columnCount(QModelIndex arg0)
	{
		return graph.getVertexCount();
	}
	
	@Override
	public Object headerData(int section, Orientation orientation, int role)
	{
		return super.headerData(section, orientation, role);
	}
	
	public void changeConnection(QModelIndex index)
	{
		int firstId = index.column();
		int secondId = index.row();
		
		if(firstId != secondId)
		{
			if(graph.isConection(firstId, secondId))
				graph.removeConection(firstId, secondId);
			else
				graph.addConection(firstId, secondId);
			
			dataChanged.emit(createIndex(firstId,secondId),createIndex(firstId,secondId));
			dataChanged.emit(createIndex(secondId,firstId),createIndex(secondId,firstId));
		}
	}

	public String getFileName()
	{
		return fileName;
	}

	public void load()
	{
		int row = 0;
				
		try{
			
			FileInputStream fstream = new FileInputStream(directory+"/"+fileName);
			DataInputStream in = new DataInputStream(fstream);
			BufferedReader br = new BufferedReader(new InputStreamReader(in));
			
			String line;
			String[] splitLine;
			
			int vertexCount = 0;
			 
			while ((line = br.readLine()) != null)
			{
				 splitLine = line.split(" ");
				 
				 if(row == 0)
				 {
					 vertexCount = splitLine.length;
					 
					 setVertexCount(vertexCount);
				 }
				 
				 int col = 0;
				 for (String cell : splitLine)
				 {
					if(cell.equals("1"))
						graph.addAsymerticConection(row,col);
					
					++col;
					
				}
				 
				 ++row;
			}
			
			in.close();
			
			layoutChanged.emit();
			vertexCountChanged.emit(vertexCount);
			
		} catch (Exception e){
			QMessageBox.warning(null, e.getMessage(), e.getMessage());
		}
	}
	
	public void setVertexCount(int count)
	{
		 graph.setVertexCount(count);
		 layoutChanged.emit();
		 vertexCountChanged.emit(count);
	}

	public int getVertexCount()
	{
		return graph.getVertexCount();
	}
	
	public void save()
	{
		try
		{
			FileWriter fstream = new FileWriter(directory+"/"+fileName);
			
	        BufferedWriter out = new BufferedWriter(fstream);
	        
	        int vertexCount = graph.getVertexCount(); 
	        
	        for (int i = 0; i < vertexCount; ++i)
	        	for (int j = 0; j < vertexCount; ++j)
	        	{
	        		if(graph.isConection(i, j))
	        			out.write("1");
	        		else
	        			out.write("0");
	        		
	        		if(j < vertexCount-1)
	        			out.write(" ");
	        		else
	        			out.write("\n");
	        	}
	        
	        out.close();
	        
		} catch (IOException e)
		{
			QMessageBox.warning(null, e.getMessage(), e.getMessage());
		}

	}

	public String getDirectory()
	{
		return directory;
	}

	public void generateRandomConnections(int connectionsCount)
	{
		Random random = new Random();
		
		int maxConnectionsCount = graph.getVertexCount() * (graph.getVertexCount() - 1) / 2;
		
		if(connectionsCount > maxConnectionsCount)
			connectionsCount = maxConnectionsCount;
		
		while (connectionsCount > 0)
		{
			int firstId = random.nextInt(graph.getVertexCount());
			int secondId = random.nextInt(graph.getVertexCount());
			
			if(firstId != secondId)
				if(! graph.isConection(firstId, secondId))
				{
					graph.addConection(firstId, secondId);
					--connectionsCount;
				}
		}
	}

	public Schedule getSchedule()
	{
		graph.setColor();
		return new Schedule(graph);
	}
}
